package com.heima.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.admin.mapper.AdChannelMapper;
import com.heima.admin.mapper.AdSensitiveMapper;
import com.heima.admin.service.WemediaNewsAutoScanService;
import com.heima.common.aliyun.GreeTextScan;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.exception.CustException;
import com.heima.feigns.article.ArticleFeign;
import com.heima.feigns.wemedia.WemediaFeign;
import com.heima.model.admin.pojos.AdChannel;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Version: V1.0
 */
@Service
@Slf4j
public class WemediaNewsAutoScanServiceImpl implements WemediaNewsAutoScanService {


    @Autowired
    WemediaFeign wemediaFeign;

    @Value("${file.oss.web-site}")
    private String webSite;

    @Autowired
    AdSensitiveMapper adSensitiveMapper;

    @Autowired
    AdChannelMapper adChannelMapper;

    @Autowired
    ArticleFeign articleFeign;

    @Autowired
    GreeTextScan greeTextScan;

    @Autowired
    GreenImageScan greenImageScan;

    /**
     * 自媒体文章自动审核
     * @param wmNewsId 自媒体文章id
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void autoScanByMediaNewsId(Integer wmNewsId) {
        //参数检查
        if (wmNewsId == null) {
            log.error("当前的审核id空");
            //CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
            return;
        }
        //1 根据文章的id查询自媒体文章
        WmNews wmNews = wemediaFeign.findById(wmNewsId);
        if (wmNews == null) {
            //CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST);
            log.error("审核的自媒体文章不存在，自媒体的id:{}", wmNewsId);
            return;
        }

        //2 文章状态=4（人工审核通过） 且发布时间小于等于当前时间，直接保存
        if (wmNews.getStatus().equals(WmNews.Status.ADMIN_SUCCESS.getCode())
                && wmNews.getPublishTime().getTime() <= System.currentTimeMillis()) {
            // 保存apArticle文章
            saveAppArticle(wmNews);
            return;
        }

        //3 文章状态=8（文章审核通过，未发布） 且发布时间小于等于当前时间，直接保存
        if (wmNews.getStatus().equals(WmNews.Status.SUCCESS.getCode())
                && wmNews.getPublishTime().getTime() <= System.currentTimeMillis()) {
            // 保存apArticle文章
            saveAppArticle(wmNews);
            return;
        }
        //4 文章状态=1 未审核
        if (wmNews.getStatus().equals(WmNews.Status.SUBMIT.getCode())) {
            // 解析文章中的内容 {"content":"", "images": ["/a/1.jpg",""]}
            Map<String,Object> contentAndImagesResult = handleTextAndImages(wmNews);

            //4.1 审核自管理的敏感词
            boolean isSensitiveScan = handleSensitive((String) contentAndImagesResult.get("content"),wmNews);
            if (!isSensitiveScan) return;

/*
            //4.2 审核文本内容-阿里云
            boolean isTextScan = handleTextScan((String) contentAndImagesResult.get("content"),wmNews);
            if (!isTextScan) return;

            //4.3 审核图片-阿里云
            boolean isImageScan = handleImageScan((List) contentAndImagesResult.get("images"),wmNews);
            if (!isImageScan) return;
*/

            //4.4 如果发布时间 大于 当前时间， 修改wmNews 文章状态=8
            if (wmNews.getPublishTime().getTime() > System.currentTimeMillis()) {
                updateNews(wmNews, WmNews.Status.SUCCESS.getCode(), "文章审核通过，待发布");
                return;
            }

            //5 审核通过，保存文章相关信息（三张表）， 修改文章的状态=9 已发布
            saveAppArticle(wmNews);

            //TODO 6 ES同步索引库
        }

    }

    /**
     * 阿里云-图片审核
     * @param images
     * @param wmNews
     * @return
     */
    private boolean handleImageScan(List<String> images, WmNews wmNews) {

        // 无图则无需审核
        if (images == null || images.size() == 0) {
            return true;
        }

        boolean flag = true;
        try {
            // 图片去重
            images = images.stream().distinct().collect(Collectors.toList());

            Map map = greenImageScan.imageUrlScan(images);


            // 审核失败
            if (map.get("suggestion").equals("block")) {
                flag = false;
                updateNews(wmNews, WmNews.Status.FAIL.getCode(), "阿里云审核-文章图片违规");
            }

            // 人工审核
            if (map.get("suggestion").equals("review")) {
                flag = false;
                updateNews(wmNews, WmNews.Status.ADMIN_AUTH.getCode(), "需要人工审核");
            }


        } catch (Exception e) {
            e.printStackTrace();
            flag = false;
            updateNews(wmNews, WmNews.Status.ADMIN_AUTH.getCode(), "需要人工审核");
        }


        return flag;
    }



    /**
     * 阿里云审核文章内容
     * @param content
     * @param wmNews
     * @return
     */
    private boolean handleTextScan(String content, WmNews wmNews) {

        boolean flag = true;

        try {
            Map map = greeTextScan.greeTextScan(content);

            // 审核失败
            if (map.get("suggestion").equals("block")) {
                flag = false;
                updateNews(wmNews, WmNews.Status.FAIL.getCode(), "阿里云审核-文章内容中包含违规内容");
            }

            // 人工审核
            if (map.get("suggestion").equals("review")) {
                flag = false;
                updateNews(wmNews, WmNews.Status.ADMIN_AUTH.getCode(), "需要人工审核");
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.error(" aliyun handleTextScan error:{} ",e);
            flag = false;
            updateNews(wmNews, WmNews.Status.ADMIN_AUTH.getCode(), "阿里云审核失败，转入人工审核");
        }

        return flag;
    }

    /**
     * 自管理敏感词审核
     * @param content
     * @param wmNews
     * @return
     */
    private boolean handleSensitive(String content, WmNews wmNews) {

        boolean flag = true;

        // 数据库获取敏感词列表-- 缓存Redis
        List<String> sensitives = adSensitiveMapper.findAllSensitive();
        // 初始化 DFA搜索词库
        SensitiveWordUtil.initMap(sensitives);

        Map<String, Integer> map = SensitiveWordUtil.matchWords(content);

        // 有敏感词
        if (map.size() > 0) {
            updateNews(wmNews, WmNews.Status.FAIL.getCode(), "文章中包含自管理敏感词"+map);
            flag = false;
        }

        return flag;
    }

    /**
     * 修改自媒体文章
     * @param wmNews 文章
     * @param status 状态
     * @param reason 拒绝理由
     */
    public void updateNews(WmNews wmNews, Short status, String reason) {
        // 修改wmNews 状态 理由
        wmNews.setStatus(status);
        wmNews.setReason(reason);
        ResponseResult result = wemediaFeign.updateWmNews(wmNews);

        if (result.getCode() != 0) {
            CustException.cust(AppHttpCodeEnum.WEMEDIA_UPDATE_ERROR);
        }
    }


    /**
     * 解析文章中文本和图片（封面图片）
     * @param wmNews
     * @return
     */
    private Map<String, Object> handleTextAndImages(WmNews wmNews) {

        String content = wmNews.getContent();
        if (StringUtils.isNotBlank(content) && content.length() < 10000) {

            List<Map> contentList = JSON.parseArray(content, Map.class);

            // 文本
            StringBuilder sb = new StringBuilder();
            // 文章标题
            sb.append(wmNews.getTitle()).append("__hmtt__");

            // 图片列表
            List<String> images = new ArrayList<>();

            for (Map<String, String> map : contentList) {

                // 文本
                if (map.get("type").equals("text")) {
                    // fhasfsa 破冰
                    // 毒素dgfasjhfas
                    // 冰毒

                    sb.append(map.get("value"));
                    // 处理拼接出现敏感词问题
                    sb.append("__hmtt__");
                }
                // 图片（有前缀）
                if (map.get("type").equals("image")) {
                    images.add(map.get("value"));
                }
            }

            // 解析 封面图片
            String wmNewsImages = wmNews.getImages();
            if (StringUtils.isNotBlank(wmNewsImages)) {
                String[] split = wmNewsImages.split(",");
                for (String url : split) {
                    images.add(webSite + url);
                }
            }


            // 返回结果
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("content", sb.toString());
            resultMap.put("images", images);

            return resultMap;
        }

        return null;
    }

    /**
     * 保存apArticle文章  审核通过文章
     *
     * 远程发起调用  保存文章三张表数据
     * @param wmNews
     */
    private void saveAppArticle(WmNews wmNews) {
//        System.out.println("saveAppArticle");

        // result 返回Article 文章ID
        ResponseResult result = saveArticle(wmNews);
        if (result.getCode() != 0) {
            CustException.cust(AppHttpCodeEnum.ARTICLE_SAVE_ERROR);
        }

        Object data = result.getData();
        wmNews.setArticleId((Long) data);
        updateNews(wmNews, WmNews.Status.PUBLISHED.getCode(), "审核通过，已发布");
    }



    private ResponseResult saveArticle(WmNews wmNews) {
        ArticleDto articleDto = new ArticleDto();

        BeanUtils.copyProperties(wmNews, articleDto);
        // 文章id存在 saveArticle 执行修改操作
        if (wmNews.getArticleId() != null) {
            articleDto.setId(wmNews.getArticleId());
        }

        // 设置作者信息
        WmUser wmUser = wemediaFeign.findWmUserById(wmNews.getUserId());
        if (wmUser != null) {
            //作者名称
            articleDto.setAuthorName(wmUser.getName());
            // 作者id ，尽量少发起远程调用
        }
        // 设置频道数据
        AdChannel adChannel = adChannelMapper.selectById(wmNews.getChannelId());
        if (adChannel != null) {
            articleDto.setChannelId(adChannel.getId());
            articleDto.setChannelName(adChannel.getName());
        }
        // 文章布局
        articleDto.setLayout(wmNews.getType().intValue());
        articleDto.setFlag((byte) 0);
        articleDto.setCreatedTime(new Date());
        articleDto.setOrigin(true);

        // 返回值 包含article 文章ID
        return articleFeign.saveArticle(articleDto);
    }
}
